unit AnaliseDM;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, DB, FileUtil, LResources, Forms, Controls, Graphics,
  Dialogs, ZDataset, ZSqlUpdate, ZSequence, TransactionDM, QueryConditions;

type

  { TAnaliseData }

  TAnaliseData = class(TTransactionDataModule)
    AmostraDatasource: TDatasource;
    AnaliseDatasource: TDatasource;
    AmostraZQuery: TZQuery;
    AmostraZQueryareia: TFloatField;
    AmostraZQueryargila: TFloatField;
    AmostraZQueryclassificacao: TStringField;
    AmostraZQueryid_amostra: TLongintField;
    AmostraZQueryid_analise: TLongintField;
    AmostraZQuerypeso_becker_1: TLongintField;
    AmostraZQuerypeso_becker_2: TLongintField;
    AmostraZQuerypeso_volume_pipetado_1: TLongintField;
    AmostraZQuerypeso_volume_pipetado_2: TLongintField;
    AmostraZQueryreferencia_cliente: TStringField;
    AmostraZQueryreferencia_laboratorio: TLongintField;
    AmostraZQuerysilte: TFloatField;
    AnaliseZQuery: TZQuery;
    AnaliseZQuerydata: TDateField;
    AnaliseZQueryid_analise: TLongintField;
    AnaliseZQueryid_produtor: TLongintField;
    AnaliseZQueryid_tecnico: TLongintField;
    AnaliseZQuerynome_produtor: TStringField;
    AnaliseZQuerynome_tecnico: TStringField;
    AnaliseZQuerynumero_registro: TLongintField;
    AnaliseZQueryvalor: TFloatField;
    AmostraZSequence: TZSequence;
    AnaliseZSequence: TZSequence;
    AmostraZUpdate: TZUpdateSQL;
    AnaliseZUpdate: TZUpdateSQL;
    /// Criação do módulo de dados
    procedure AnaliseZQueryAfterInsert(DataSet: TDataSet);
    procedure DataModuleCreate(Sender: TObject);
    /// Abre o DataSet
    procedure OpenDataSet; override;
    /// Fehca o DataSet
    procedure CloseDataSet; override;
    /// Realiza busca
    /// @param(Condicoes são as condições para a busca)
    /// @param(Tabela é a tabela no banco de dados)
    procedure Search(Condicoes: TQueryConditions; Tabela: string); override;
    /// Gravação dos DataSets detalhe
    procedure PostDetail; override;
    /// Na validação dos campos peso_becker e volume_pipetado
    procedure AmostraZQuerypeso_becker_1Validate(Sender: TField);
    /// Retorna o código da analise atual
    function GetCurrentIdAnalise(): integer;
  protected
    /// Deleta os dados dos DataSets detalhe
    procedure DeleteDetail; override;
  private
    /// Realiza os cálculos sobre uma amostra
    procedure AmostraClassifica();
  end;

var
  AnaliseData: TAnaliseData;

implementation

uses ConnectionDM, LaboratorioDM, CalculosClassificacao, DataRecord;

{ TAnaliseData }

procedure TAnaliseData.DataModuleCreate(Sender: TObject);
begin
  // Atribui o DataSet principal
  MainDataSet := AnaliseZQuery;
end;

procedure TAnaliseData.AnaliseZQueryAfterInsert(DataSet: TDataSet);
var
  D:TDataRecord;
begin
  D:=LaboratorioData.GetDataRecord();
  if D <> nil then begin
    D.WriteToDataSet(AnaliseZQuery);
  end;
end;

procedure TAnaliseData.OpenDataSet;
begin
  // Abre o DataSet principal
  ConnectionData.EmptyQuery(AnaliseZQuery, 'analise');
  // Abre o DataSet filho
  AmostraZQuery.Open;
end;

procedure TAnaliseData.CloseDataSet;
begin
  // Cancela possível transação ativa
  if AnaliseZQuery.Connection.InTransaction then
    AnaliseZQuery.Connection.Rollback();
  // Fecha os DataSets
  AnaliseZQuery.Close();
  AmostraZQuery.Close();
end;

procedure TAnaliseData.Search(Condicoes: TQueryConditions; Tabela: string);
begin
  ConnectionData.OpenQueryConditions(AnaliseZQuery, Tabela, Condicoes);
end;

procedure TAnaliseData.DeleteDetail();
var
  ZQ: TZQuery;
begin
  // Verifica se há registros no DataSet principal
  if AnaliseZQuery.RecordCount > 0 then begin
    // Deleta os registros dos DataSets detalhe
    ZQ := TZQuery.Create(nil);
    ZQ.Connection := ConnectionData.PrincipalZConnection;
    ZQ.SQL.Clear;
    ZQ.SQL.Add('DELETE FROM amostra');
    ZQ.SQL.Add('WHERE id_analise = :id_analise');
    ZQ.ParamByName('id_analise').AsString := AnaliseZQueryid_analise.AsString;
    ZQ.ExecSQL();
    ZQ.Close();
    ZQ.Destroy();
  end;
end;

procedure TAnaliseData.AmostraClassifica;
var
  DadosAmostra: TDadosAmostra;
  Componentes: TComponentes;
begin
  // Copia os valores de peso dos beckers e volumes pipedatos para TDadosAmostra
  DadosAmostra.peso_becker_1 := AmostraZQuery.FieldByName('peso_becker_1').AsInteger;
  DadosAmostra.peso_volume_pipetado_1 :=
    AmostraZQuery.FieldByName('peso_volume_pipetado_1').AsInteger;
  DadosAmostra.peso_becker_2 := AmostraZQuery.FieldByName('peso_becker_2').AsInteger;
  DadosAmostra.peso_volume_pipetado_2 :=
    AmostraZQuery.FieldByName('peso_volume_pipetado_2').AsInteger;
  // Calcula a porcentatem dos componentes Areia, Silte e Argila com base no TDadosAmostra
  Componentes := Porcentagens(DadosAmostra);
  // Grava os componentes no banco de dados
  AmostraZQuery.FieldByName('areia').AsFloat := Componentes.areia;
  AmostraZQuery.FieldByName('argila').AsFloat := Componentes.argila;
  AmostraZQuery.FieldByName('silte').AsFloat := Componentes.silte;
  // Obtém a classificação do solo e grava no banco de dados
  AmostraZQuery.FieldByName('classificacao').AsString := Classificacao(Componentes);
end;

procedure TAnaliseData.PostDetail;
begin
  // Atualiza o total da análise
  AnaliseZQuery.Edit();
  AnaliseZQueryvalor.Value := AmostraZQuery.RecordCount *
    LaboratorioData.GetPrecoAmostra();
  AnaliseZQuery.Post();
  // Finaliza a transação
  inherited PostDetail;
end;

procedure TAnaliseData.AmostraZQuerypeso_becker_1Validate(Sender: TField);
begin
  AmostraClassifica();
end;

function TAnaliseData.GetCurrentIdAnalise(): integer;
begin
  Result := AnaliseZQuery.FieldByName('id_analise').AsInteger;
end;

initialization
  {$I analisedm.lrs}

end.
